﻿using System;
using System.Collections.Generic;

using Microsoft.CodeAnalysis.CSharp.Syntax;
using RoslynTest.Analyzers.Lib;

namespace RoslynTest.Analyzers
{
    class Program
    {
        static void Main(string[] args)
        {            
            try
            {
                string solutionPath = System.IO.Directory.GetParent(System.IO.Directory.GetCurrentDirectory()).Parent.Parent.FullName + "\\RoslynTest.sln";
                MethodLocator methodLocator = new MethodLocator
                {
                    FilePath = System.IO.Directory.GetParent(System.IO.Directory.GetCurrentDirectory()).Parent.FullName + "\\Sample\\SampleClass.cs",
                    MethodName = "Method1",
                    MethodParametersNumber = 0
                };

                int num;
                if (args.Length == 4 && int.TryParse(args[3], out num))
                {
                    solutionPath = args[0];
                    methodLocator = new MethodLocator
                    {
                        FilePath = args[1],
                        MethodName = args[2],
                        MethodParametersNumber = num
                    };
                }
                                
                //  analyze
                var sequenceAnalyzer = new SequenceAnalyzer(solutionPath);
                var graph = sequenceAnalyzer.FindMethodCallingSequence(methodLocator).Result;

                //  display
                WriteToConsole(graph);
            }
            catch (AggregateException ae)
            {
                Console.WriteLine("Exception occured:");
                foreach (var exception in ae.InnerExceptions)
                {
                    Console.WriteLine(exception.Message);
                }
                Console.WriteLine("Press any key to exit...");
                Console.ReadKey();
            }
           
         }

        private static void WriteToConsole(IEnumerable<NodeWithChildren<MethodDeclarationSyntax>> graph)
        {
            foreach (var vertex in graph)
            {
                Console.ForegroundColor = ConsoleColor.Cyan;
                var callingClass = vertex.Node.Parent.FirstAncestorOrSelf<ClassDeclarationSyntax>();
                Console.WriteLine(string.Format("{0}{1} {2}->{3}", new string(' ', vertex.Depth), vertex.Depth, callingClass.Identifier.ValueText, vertex.Node.Identifier.ValueText));
                Console.ResetColor();

                foreach (var reference in vertex.Children)
                {
                    var refCallingClass = reference.Parent.FirstAncestorOrSelf<ClassDeclarationSyntax>();
                    Console.WriteLine(string.Format("{0}ref from ({1}->{2})", new string(' ', vertex.Depth + 1), refCallingClass.Identifier.ValueText, reference.Identifier.ValueText));
                }
            }

            Console.WriteLine();
            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }
    }
}
